package data

import (
	"context"
	"platform-sastay-file/internal/conf"
	"time"

	"github.com/go-kratos/kratos/contrib/registry/etcd/v2"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-redis/redis/v8"
	"github.com/google/wire"
	clientv3 "go.etcd.io/etcd/client/v3"
)

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewRegistry, NewRedis, NewNodeRepo, NewDomainNameRepo, NewClusterRepo)

// Data .
type Data struct {
	// TODO wrapped database client
	registry *etcd.Registry // 服务发现
	redis    *redis.Client
}

// NewData .
func NewData(c *conf.Data, logger log.Logger, r *etcd.Registry, redis *redis.Client) (*Data, func(), error) {
	cleanup := func() {
		log.NewHelper(logger).Info("closing the data resources")
	}
	return &Data{
		registry: r,
		redis:    redis,
	}, cleanup, nil
}

// NewRegistry 服务发现
func NewRegistry(c *conf.Data) *etcd.Registry {
	client, err := clientv3.New(clientv3.Config{
		Endpoints:   c.Etcd.Endpoints,
		DialTimeout: c.Etcd.DialTimeout.AsDuration(),
	})
	if err != nil {
		log.Fatalf("new etcd client err: ", err.Error())
	}
	return etcd.New(client, etcd.RegisterTTL(c.Etcd.Ttl.AsDuration()))
}

// NewRedis redis
func NewRedis(c *conf.Data) *redis.Client {
	client := redis.NewClient(&redis.Options{
		Network:      c.Redis.Network,
		Addr:         c.Redis.Addr,
		Password:     c.Redis.Password,
		DB:           int(c.Redis.Db),
		PoolSize:     int(c.Redis.PoolSize),
		ReadTimeout:  c.Redis.ReadTimeout.AsDuration(),
		WriteTimeout: c.Redis.WriteTimeout.AsDuration(),
	})
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	_, err := client.Ping(ctx).Result()
	if err != nil {
		log.Fatalf("new redis client err: ", err)
	}
	return client
}
